
#ifndef __OgreApp_h_
#define __OgreApp_h_
#include <iostream>
#include <Ogre.h>

class OgreApp
{
public:
    void go()
    {
        createRoot();
        defineResources();
        setupRenderSystem();
        createRenderWindow();
        initializeResourceGroups();
        createScene();
		
        setupInputSystem();
        setupCEGUI();
        createFrameListener();
        startRenderLoop();
    }

    virtual ~OgreApp()
    {
		mInputManager->destroyInputObject(mKeyboard);
		mInputManager->destroyInputObject(mMouse);
		OIS::InputManager::destroyInputSystem(mInputManager);
//		delete mListener;
		delete mRoot;
//		delete gui;
    }

protected:
	Ogre::Root *mRoot;
    OIS::Keyboard *mKeyboard;
    OIS::Mouse *mMouse;
    OIS::InputManager *mInputManager;
	//BufferedInputHandler *mListener;
//    CEGUI::OgreCEGUIRenderer *mRenderer;
//    CEGUI::System *mSystem;
    
	Ogre::RenderWindow *win;


    void createRoot()
    {
		mRoot = new Ogre::Root();

    }
    
    void defineResources()
    {
		Ogre::String secName, typeName, archName;
		Ogre::ConfigFile cf;
		cf.load("resources.cfg");
		Ogre::ConfigFile::SectionIterator seci = cf.getSectionIterator();
		while (seci.hasMoreElements())
		{
			secName = seci.peekNextKey();
			Ogre::ConfigFile::SettingsMultiMap *settings = seci.getNext();
			Ogre::ConfigFile::SettingsMultiMap::iterator i;
			for (i = settings->begin(); i != settings->end(); ++i)
			{
				typeName = i->first;
				archName = i->second;
				Ogre::ResourceGroupManager::getSingleton().addResourceLocation(archName, typeName, secName);
			}
       }



    }
    
    void setupRenderSystem()
    {
		 if (!mRoot->restoreConfig() && !mRoot->showConfigDialog())
			 throw Ogre::Exception(52, "User canceled the config dialog!", "OgreApp::setupRenderSystem()");

    }
    
    void createRenderWindow()
    {
		mRoot->initialise(true, "Hamer Delta Map Editor");

    }

    void initializeResourceGroups()
    {
		Ogre::TextureManager::getSingleton().setDefaultNumMipmaps(5);
		Ogre::ResourceGroupManager::getSingleton().initialiseAllResourceGroups();

    }

    virtual void createScene()
    {
		//gui = new Gui(mRoot);


    }

    void setupInputSystem()
    {
		size_t windowHnd = 0;
		std::ostringstream windowHndStr;
		OIS::ParamList pl;
		win = mRoot->getAutoCreatedWindow();

		win->getCustomAttribute("WINDOW", &windowHnd);
		windowHndStr << windowHnd;
		pl.insert(std::make_pair(std::string("WINDOW"), windowHndStr.str()));
		mInputManager = OIS::InputManager::createInputSystem(pl);
		try
		{
			mKeyboard = static_cast<OIS::Keyboard*>(mInputManager->createInputObject(OIS::OISKeyboard, true));
			mMouse = static_cast<OIS::Mouse*>(mInputManager->createInputObject(OIS::OISMouse, true));
		}
		catch (const OIS::Exception &e)
		{
			throw Ogre::Exception(42, e.eText, "OgreApp::setupInputSystem");
		}
		

    }

    virtual void setupCEGUI()
    {
		//CEGUI::WindowManager *wmgr = CEGUI::WindowManager::getSingletonPtr();
		//CEGUI::Window *quit = wmgr->getWindow((CEGUI::utf8*)"CEGUIDemo/QuitButton");
		//quit->subscribeEvent(
		//	CEGUI::PushButton::EventClicked, 
		//	CEGUI::Event::Subscriber(&BufferedInputHandler::quit, mListener));

    }

    virtual void createFrameListener()
    {

    }

    void startRenderLoop()
    {
		mRoot->startRendering();

    }
};

#endif // #ifndef __MapEditor_h_